package com.plm.k8s.myk8sapi.cmd.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.plm.k8s.myk8sapi.cmd.AbstractLocalCmd;
import com.plm.k8s.myk8sapi.cmd.IServiceCmd;
import com.plm.k8s.myk8sapi.pojo.entity.service.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 潘磊明
 * 版本号：1.0
 * 创建日期：2021/7/26 14:35
 */
@Service
public class ServiceCmdImpl extends AbstractLocalCmd implements IServiceCmd {

    @Override
    public List<ServiceEntity> listService(boolean isAll, String namespace, String nameFilter,
            Map<String, String> labelFilter) throws Exception {
        String cmd = generateListServiceCmd(isAll, namespace, nameFilter, labelFilter);
        ApiServiceEntity serviceEntity = execForYamlObject(cmd, ApiServiceEntity.class);
        if (serviceEntity == null) return Collections.emptyList();
        return serviceEntity.getItems();
    }

    @Override
    public boolean createService(File yamlFile) throws Exception {
        String result = applyYamlFile(yamlFile);
        if (!result.contains("created")) {
            throw new Exception(result);
        }
        return true;
    }

    @Override
    public boolean createService(String name, String namespace, Map<String, String> selector, String type
            , List<ServiceSpecPortEntity> ports) throws Exception {
        return createService(name, namespace, selector, type, ports, null);
    }

    @Override
    public boolean createService(String name, String namespace, Map<String, String> selector, String type,
            List<ServiceSpecPortEntity> ports, Map<String, String> labels) throws Exception {
        if (!StringUtils.hasText(name)) throw new Exception("服务名称不能为空");
        ServiceEntity serviceEntity = generateBaseService(name);
        setMoreServiceInfo(serviceEntity, namespace, selector, type, ports, labels);
        File yamlFile = transferObject2YamlFile(serviceEntity);
        return createService(yamlFile);
    }

    @Override
    public boolean deleteService(String name, String namespace, boolean isForce) throws Exception {
        if (!StringUtils.hasText(name)) throw new Exception("服务名称不能为空");
        String cmd = generateDeleteServiceCmd(name, namespace, isForce);
        String result = exec(cmd);
        if (!String.format("service \"%s\" deleted", name).equals(trimBr(result))) {
            throw new Exception(result);
        }
        return true;
    }

    private String generateDeleteServiceCmd(String name, String namespace, boolean isForce) {
        StringBuilder sb = new StringBuilder(generateKubeCmdBase());
        sb.append("delete svc ").append(name);
        if (StringUtils.hasText(namespace)) sb.append(CMD_DELIMITER).append("-n ").append(namespace);
        sb.append(CMD_DELIMITER).append("--force=").append(isForce);
        return sb.toString();
    }


    private void setMoreServiceInfo(ServiceEntity serviceEntity, String namespace, Map<String, String> selector,
            String type, List<ServiceSpecPortEntity> ports, Map<String, String> labels) {
        if (StringUtils.hasText(namespace)) serviceEntity.getMetadata().setNamespace(namespace);
        ServiceSpecEntity specEntity = serviceEntity.getSpec();
        if (CollectionUtil.isNotEmpty(selector)) specEntity.setSelector(selector);
        if (StringUtils.hasText(type)) specEntity.setType(type);
        if (CollectionUtil.isNotEmpty(ports)) specEntity.setPorts(ports);
        if (!CollectionUtil.isEmpty(labels)) serviceEntity.getMetadata().setLabels(labels);
    }

    /**
     * 生成基础的service
     * @param name
     * @return
     */
    private ServiceEntity generateBaseService(String name) {
        ServiceEntity serviceEntity = new ServiceEntity();
        serviceEntity.setApiVersion("v1");
        serviceEntity.setKind("Service");
        ServiceMetadataEntity metadataEntity = new ServiceMetadataEntity();
        Map<String, String> labels = new LinkedHashMap<>();
        labels.put("app", name);
        metadataEntity.setLabels(labels);
        metadataEntity.setName(name);
        serviceEntity.setMetadata(metadataEntity);
        ServiceSpecEntity specEntity = new ServiceSpecEntity();
        serviceEntity.setSpec(specEntity);
        ServiceStatusEntity statusEntity = new ServiceStatusEntity();
        ServiceStatusLoadBalancerEntity loadBalancerEntity = new ServiceStatusLoadBalancerEntity();
        statusEntity.setLoadBalancer(loadBalancerEntity);
        serviceEntity.setStatus(statusEntity);
        return serviceEntity;
    }


    private String generateListServiceCmd(boolean isAll, String namespace, String nameFilter, Map<String, String> labelFilter) {
        StringBuilder sb = new StringBuilder(generateKubeCmdBase());
        sb.append("get svc -o yaml ");
        if (isAll) {
            sb.append("-A");
        } else {
            if (StringUtils.hasText(namespace)) addNamespace(sb, namespace);
        }
        if (StringUtils.hasText(nameFilter)) addNameFilter(sb, nameFilter);
        if (CollectionUtil.isNotEmpty(labelFilter)) addLabelFilter(sb, labelFilter);
        return sb.toString();
    }
}
